
#ifndef INTERPRETER_H
#define INTERPRETER_H

#include <vector>
#include <string>

#include "Block.h"
#include "Config.h"
#include "Disk.h"
#include "Field.h"
#include "Schema.h"
#include "Relation.h"
#include "MainMemory.h"
#include "SchemaManager.h"
#include "Tuple.h"

class Interpreter
{

public:

	static Interpreter* GetInstance() 
	{ 
		if(mIP == NULL) 
			mIP = new Interpreter(); 
		return mIP; 
	}
	static void Destroy() 
	{ 
		if(mIP != NULL) 
		{
			delete mIP;
			mIP = NULL;
		}
	}
	
	int Interpret(std::string& query);
	///// tanzir
	void naturaljoin ();
	void printtableinfo (string tablename);
	void sorttuples (vector<Tuple> &tuples, int orderindex);
	void sorttuples (vector<Tuple> &tuples, vector<int> orderindices);
	void printtabledata (Relation *rel_ptr);
	void mergetables (vector <string> & tables, vector<int> col_indices);
	void selectwithorderby (string relname, string orderbycolumn);
	void createrelationfromtuples (vector<Tuple> tuples, string giventablename);
	


	///// end tanzir

private:

	Interpreter(): mSchemaManager(&mMem, &mDisk) {};
	
	int HandleCreate();
	int HandleDrop();
	int HandleSelect();
	int HandleDelete();
	int HandleInsert();

	



	int AppendTupleToRelation (Relation* relation_ptr, int memory_block_index, Tuple& tuple);
	// this following function add all the tuples in the vector to the relation using memory block that is given
	int AppendTuplesToRelation (Relation* relation_ptr, int memory_block_index, vector <Tuple> & tuples);
	
	bool CheckWhereOnTuple(const Tuple& tuple, const std::vector<std::string>& whereRPN) const;

	int GetCrossJoinedSchema(const std::vector<std::string>& tableNames, 
			std::vector<std::string>& resultFieldNames, 
			std::vector<enum FIELD_TYPE>& resultFieldTypes);

	std::string GetCrossJoinedName(std::vector<std::string>& tableNames) const;

	std::vector<std::string> mTokens;

	MainMemory mMem;
	Disk mDisk;
	SchemaManager mSchemaManager;

	static Interpreter* mIP;
};

#endif // INTERPRETER_H
